/*
 * Copyright 2016 - 2020 Michael Rapp
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package de.mrapp.tabswitcher.model;

import de.mrapp.tabswitcher.ResourceTable;
import de.mrapp.tabswitcher.Tab;
import de.mrapp.tabswitcher.TabSwitcher;
import de.mrapp.tabswitcher.util.ThemeHelper;
import de.mrapp.util.Condition;
import ohos.agp.components.element.*;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextTool;
import ohos.app.Context;
import ohos.global.resource.Resource;
import ohos.global.resource.solidxml.Theme;

public class TabSwitcherStyle {

    /**
     * The tab switcher, whose style attributes are retrieved.
     */
    private final TabSwitcher tabSwitcher;

    /**
     * The theme helper, which allows to retrieve resources, depending on the tab switcher's theme.
     */
    private final ThemeHelper themeHelper;

    /**
     * The model of the tab switcher, whose style attributes are retrieved.
     */
    private final Model model;


    /**
     * Return the color state list, which should be used to tint the icon of tabs.
     *
     * @param tab The tab, the color state list should be returned for, as an instance of the class
     *            {@link Tab} or null, if the color state list should not be returned for a specific
     *            tab
     * @return The color state list, which should be used to tint the icon of tabs, as an instance
     * of the class {@link Color} or null, if the icon should not be tinted
     */

    private Color getTabIconTintList(final Tab tab) {
        Color tintList = tab != null ? tab.getCloseButtonIconTintList() : null;

        if (tintList == null) {
            tintList = model.getTabCloseButtonIconTintList();

            if (tintList == null) {
                try {
//                    tintList = themeHelper.getColorStateList(tabSwitcher.getLayout(),
//                            R.attr.tabSwitcherTabIconTint);
                } catch (Exception e) {
                    tintList = null;
                }

            }
        }

        return tintList;
    }

    /**
     * Returns the mode, which should be used to tint the icon of tabs.
     *
     * @param tab The tab, the mode should be returned for, as an instance of the class {@link Tab} or
     *            null, if the mode should not be returned for a specific tab
     * @return The mode, which should be used to tint the icon of tabs, as a value of the enum
     * {@link ohos.agp.render.Canvas.PorterDuffMode}. The mode may not be null
     */

    private Canvas.PorterDuffMode getTabIconTintMode(final Tab tab) {
        Canvas.PorterDuffMode tintMode = tab != null ? tab.getIconTintMode() : null;

        if (tintMode == null) {
            tintMode = model.getTabIconTintMode();
        }

        return tintMode != null ? tintMode : Canvas.PorterDuffMode.SRC_ATOP;
    }

    /**
     * Return the color state list, which should be used to tint the close button of tabs.
     *
     * @param tab The tab, the color state list should be returned for, as an instance of the class
     *            {@link Tab} or null, if the color state list should not be returned for a specific
     *            tab
     * @return The color state list, which should be used to tint the close button of tabs, as an
     * instance of the class {@link Color} or null, if the close button should not be
     * tinted
     */

    private Color getTabCloseButtonIconTintList(final Tab tab) {
        Color tintList = tab != null ? tab.getCloseButtonIconTintList() : null;

        if (tintList == null) {
            tintList = model.getTabCloseButtonIconTintList();

            if (tintList == null) {
                try {
//                    tintList = themeHelper.getColorStateList(tabSwitcher.getLayout(),
//                            R.attr.tabSwitcherTabCloseButtonIconTint);
                } catch (Exception e) {
                    tintList = null;
                }

            }
        }

        return tintList;
    }

    /**
     * Returns the mode, which should be used to tint the close button of tabs.
     *
     * @param tab The tab, the mode should be returned for, as an instance of the class {@link Tab} or
     *            null, if the mode should not be returned for a specific tab
     * @return The mode, which should be used to tint the close button of tabs, as a value of the
     * enum {@link Canvas.PorterDuffMode}. The mode may not be null
     */

    private Canvas.PorterDuffMode getTabCloseButtonIconTintMode(final Tab tab) {
        Canvas.PorterDuffMode tintMode = tab != null ? tab.getCloseButtonIconTintMode() : null;

        if (tintMode == null) {
            tintMode = model.getTabCloseButtonIconTintMode();
        }

        return tintMode != null ? tintMode : Canvas.PorterDuffMode.SRC_ATOP;
    }

    /**
     * Return the color state list, which should be used to tint the navigation icon of the toolbar,
     * which is shown, when the tab switcher is shown.
     *
     * @return The color state list, which should be used to tint the navigation icon of the
     * toolbar, which is shown, then the tab switcher is shown, as an instance of the class {@link
     * Color} or null, if the navigation icon should not be tinted
     */

    private Color getToolbarNavigationIconTintList() {
        Color tintList = model.getTabCloseButtonIconTintList();

        if (tintList == null) {
            try {
//                tintList = themeHelper.getColorStateList(tabSwitcher.getLayout(),
//                        R.attr.tabSwitcherToolbarNavigationIconTint);
            } catch (Exception e) {
                tintList = null;
            }

        }

        return tintList;
    }

    /**
     * Returns the mode, which should be used to tint the navigation icon of the toolbar, which is
     * shown, when the tab switcher is shown.
     *
     * @return The mode, which should be used to tint the navigation icon of the toolbar, which is
     * shown, when the tab switcher is shown, as a value of the enum {@link Canvas.PorterDuffMode}. The
     * mode may not be null
     */

    private Canvas.PorterDuffMode getToolbarNavigationIconTintMode() {
        Canvas.PorterDuffMode tintMode = model.getToolbarNavigationIconTintMode();
        return tintMode != null ? tintMode : Canvas.PorterDuffMode.SRC_ATOP;
    }

    /**
     * Creates a new class, which allows to retrieve the style attributes of a {@link TabSwitcher}.
     *
     * @param tabSwitcher The tab switcher, whose style attributes are retrieved, as an instance of the type
     *                    {@link TabSwitcher}. The tab switcher may not be null
     * @param model       The model of the tab switcher, whose style attributes are retrieved, as an instance
     *                    of the class {@link TabSwitcher}. The model may not be null
     * @param themeHelper The theme helper, which allows to retrieve resources, depending on the tab switcher's
     *                    theme, as an instance of the class {@link ThemeHelper}. The theme helper may not be
     *                    null
     */
    public TabSwitcherStyle(final TabSwitcher tabSwitcher, final Model model,
                            final ThemeHelper themeHelper) {
        Condition.INSTANCE.ensureNotNull(tabSwitcher, "The tab switcher may not be null");
        Condition.INSTANCE.ensureNotNull(model, "The model may not be null");
        Condition.INSTANCE.ensureNotNull(themeHelper, "The theme helper may not be null");
        this.tabSwitcher = tabSwitcher;
        this.model = model;
        this.themeHelper = themeHelper;
    }

    /**
     * Returns the theme helper, which allows to retrieve resources, depending on the tab switcher's
     * theme.
     *
     * @return The theme helper, which allows to retrieve resources, depending on the tab switcher's
     * theme, as an instance of the class {@link ThemeHelper}. The theme helper may not be null
     */

    public final ThemeHelper getThemeHelper() {
        return themeHelper;
    }

    /**
     * Returns the icon of tabs.
     *
     * @param tab The tab, the icon should be returned for, as an instance of the class {@link Tab} or
     *            null, if the icon should not be returned for a specific tab
     * @return The icon of tabs as an instance of the class {@link Element} or null, if no icon is
     * set
     */

    public final Element getTabIcon(final Tab tab) {
        Element icon = tab != null ? tab.getIcon(model.getContext()) : null;

        if (icon == null) {
            icon = model.getTabIcon();

            if (icon == null) {
                try {
                    //未找到ColotStateList 修改图片颜色，故使用两张图片切换
                    boolean darkTheme = "dark".equals(getThemeValue("theme_name"));
                    icon = new VectorElement(tabSwitcher.getContext(), darkTheme ? ResourceTable.Media_ic_file_outline_18dp_white : ResourceTable.Media_ic_file_outline_18dp);
                } catch (Exception e) {
                    icon = null;
                }
            }
        }

        if (icon != null) {
            Color tintList = getTabIconTintList(tab);

            if (tintList != null) {
                Canvas.PorterDuffMode tintMode = getTabIconTintMode(tab);
//                DrawableCompat.setTintList(icon, tintList);
//                DrawableCompat.setTintMode(icon, tintMode);
            }
        }

        return icon;
    }

    private String getThemeValue(String name) {
        Theme theme = tabSwitcher.getContext().getTheme();
        String theme_name = "";
        try {
            theme_name = theme.getStringValue(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return theme_name;
    }

    /**
     * Returns the background color of tabs.
     *
     * @param tab The tab, the background color should be returned for, as an instance of the class
     *            {@link Tab} or null, if the background color should not be returned for a specific
     *            tab
     * @return The background color of tabs as an instance of the class {@link Color}
     */
    public final Color getTabBackgroundColor(final Tab tab) {
        Color colorStateList = tab != null ? tab.getBackgroundColor() : null;

        if (colorStateList == null) {
            colorStateList = model.getTabBackgroundColor();

            if (colorStateList == null) {
//                colorStateList = themeHelper.getColorStateList(tabSwitcher.getLayout(),
//                        R.attr.tabSwitcherTabBackgroundColor);
            }
        }

        return colorStateList;
    }

    public final int getTabTitleBackgroundColor(final Tab tab) {
        int color = tab != null ? tab.getContentBackgroundColor() : -1;

        if (color == -1) {
            //使用主题色来配置Tab背景
            color = model.getTabTitleBackgroundColor();

            if (color == -1) {
                boolean darkTheme = "dark".equals(getThemeValue("theme_name"));
                color = tabSwitcher.getContext().getColor(darkTheme ? ResourceTable.Color_phone_tab_title_background_color_dark : ResourceTable.Color_phone_tab_title_background_color_light);
            }
        }

        return color;
    }

    public final int getTabContentBackgroundColor(final Tab tab) {
        int color = tab != null ? tab.getContentBackgroundColor() : -1;

        if (color == -1) {

            color = model.getTabContentBackgroundColor();

            if (color == -1) {
                //配置Tab content背景
                boolean darkTheme = "dark".equals(getThemeValue("theme_name"));
                color = tabSwitcher.getContext().getColor(darkTheme ? ResourceTable.Color_phone_tab_content_background_color_dark : ResourceTable.Color_phone_tab_content_background_color_light);
            }
        }

        return color;
    }

    public final Element getTabBorderBackground(final Tab tab) {
        boolean darkTheme = "dark".equals(getThemeValue("theme_name"));

        int drawableRes = darkTheme ? ResourceTable.Graphic_shape_tab_background_dark : ResourceTable.Graphic_shape_tab_background;
        Element element = null;
        try {
            element = new ShapeElement(tabSwitcher.getContext(), drawableRes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return element;
    }

    public final Element getTabContentBorderBackground(final Tab tab) {
        boolean darkTheme = "dark".equals(getThemeValue("theme_name"));

        int drawableRes = darkTheme ? ResourceTable.Graphic_shape_tab_border_background_dark : ResourceTable.Graphic_shape_tab_border_background;
        Element element = null;
        try {
            element = new ShapeElement(tabSwitcher.getContext(), drawableRes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return element;
    }


    public final Color getTabTitleTextColor(final Tab tab) {
        Color colorStateList = tab != null ? tab.getTitleTextColor() : null;

        if (colorStateList == null) {
            colorStateList = model.getTabTitleTextColor();

            if (colorStateList == null) {
                boolean darkTheme = "dark".equals(getThemeValue("theme_name"));
                colorStateList = darkTheme ? Color.WHITE : new Color(Color.getIntColor("#666666"));
            }
        }

        return colorStateList;
    }

    /**
     * Returns the close button icon of tabs.
     *
     * @param tab The tab, the icon should be returned for, as an instance of the class {@link Tab} or
     *            null, if the icon should not be returned for a specific tab
     * @return The close button icon of tabs as an instance of the class {@link Element}
     */
    public final Element getTabCloseButtonIcon(final Tab tab) {
        Element icon = tab != null ? tab.getCloseButtonIcon(model.getContext()) : null;

        if (icon == null) {
            icon = model.getTabCloseButtonIcon();
            if (icon == null) {
                boolean darkTheme = "dark".equals(getThemeValue("theme_name"));
                icon = convertResToElement(model.getContext(), darkTheme ? ResourceTable.Media_phone_tab_close_button_icon_dark : ResourceTable.Media_phone_tab_close_button_icon_light);
            }
        }

        if (icon != null) {
            Color tintList = getTabCloseButtonIconTintList(tab);

            if (tintList != null) {
                Canvas.PorterDuffMode tintMode = getTabCloseButtonIconTintMode(tab);
//                DrawableCompat.setTintList(icon, tintList);
//                DrawableCompat.setTintMode(icon, tintMode);
            }
        }

        return icon;
    }

    private Element convertResToElement(Context mContext, int drawableRes) {
        Element element = null;
        try {
            Resource resource = mContext.getResourceManager().getResource(drawableRes);
            element = new PixelMapElement(resource);
            return element;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return element;
    }


    public final int getTabProgressBarColor(final Tab tab) {
        int color = tab != null ? tab.getProgressBarColor() : -1;

        if (color == -1) {
            color = model.getTabProgressBarColor();

            if (color == -1) {
//                color = themeHelper
//                        .getColor(tabSwitcher.getLayout(), R.attr.tabSwitcherTabProgressBarColor);
            }
        }

        return color;
    }


    public final Color getAddTabButtonColor() {
        Color colorStateList = model.getAddTabButtonColor();

        if (colorStateList == null) {
//            colorStateList = themeHelper.getColorStateList(tabSwitcher.getLayout(),
//                    R.attr.tabSwitcherAddTabButtonColor);
        }

        return colorStateList;
    }


    public final CharSequence getToolbarTitle() {
        CharSequence title = model.getToolbarTitle();

        if (TextTool.isNullOrEmpty(title)) {
            try {
//                title = themeHelper
//                        .getText(tabSwitcher.getLayout(), R.attr.tabSwitcherToolbarTitle);
            } catch (Exception e) {
                title = null;
            }
        }

        return title;
    }


    public final Element getToolbarNavigationIcon() {
        Element icon = model.getToolbarNavigationIcon();

        if (icon == null) {
            try {
//                themeHelper.getDrawable(tabSwitcher.getLayout(),
//                        R.attr.tabSwitcherToolbarNavigationIcon);
            } catch (Exception e) {
                icon = null;
            }
        }

        if (icon != null) {
            Color tintList = getToolbarNavigationIconTintList();

            if (tintList != null) {
                Canvas.PorterDuffMode tintMode = getToolbarNavigationIconTintMode();
//                DrawableCompat.setTintList(icon, tintList);
//                DrawableCompat.setTintMode(icon, tintMode);
            }
        }

        return icon;
    }

}